<template>
  <basic-dialog
    v-model:open="toggle"
    width="57.5rem"
    :fullscreen="isMobile"
    :z-index="isMobile ? 998 : 2000"
    :sticky-header="isMobile"
  >
    <template #title>
      <div class="_form-item" :class="{ _mobile: isMobile }">
        <label class="_label">Price By</label>
        <el-select
          v-model="params.price_by"
          size="large"
          class="_select-search-bar"
          placeholder="Recommended"
          clearable
          @change="onQuery"
        >
          <el-option v-for="item in priceBy" :key="item.value" v-bind="item" />
        </el-select>
      </div>
    </template>
    <div
      v-if="toggle"
      class="_select-pack-container"
      :class="{ _mobile: isMobile }"
    >
      <el-scrollbar class="_scroll-bar">
        <component
          ref="basicTableRef"
          class="_basic-table"
          :is="BasicTable<API.BOX.BoxListItem>"
          :request="getBoxList"
          :size="isMobile ? 10 : 20"
          :params="params"
          :field-names="{ list: 'box_list' }"
          :data-source-mode="
            !isMobile ? DataSourceMode.Pagination : DataSourceMode.Loadmore
          "
          load-more-class="bg-hex-1d1f20"
        >
          <template #default="{ list, pageSize, loading }">
            <div class="_box-list">
              <template v-if="loading && isMobile && list.length === 0">
                <box-container
                  class="_box-item"
                  v-for="loadingItem in pageSize"
                  :key="loadingItem"
                >
                  <div class="flex items-center justify-center h-full w-full">
                    <loading class="!w-2.5rem" :track-width="6" />
                  </div>
                </box-container>
              </template>
              <template v-else>
                <box-container
                  class="_box-item"
                  v-for="box in list"
                  :key="box.id"
                >
                  <div
                    class="flex flex-col items-center justify-between gap-1rem h-full w-full"
                  >
                    <div class="flex-1 h-0 w-full" @click="onSelectBox(box, 1)">
                      <img
                        class="h-full w-full"
                        style="object-fit: fill"
                        :src="box?.image"
                      />
                    </div>
                    <div class="_box-bottom" @click.stop>
                      <price-btn
                        v-if="selectedBoxMap?.[box.id]?.num === void 0"
                        :price="Number(box?.spin_amount || 0)"
                      />
                      <div v-else class="_box-number-bar">
                        <div class="_icon" @click="onSelectBox(box, -1)">
                          <el-icon>
                            <minus />
                          </el-icon>
                        </div>
                        <el-input-number
                          class="_number-box"
                          :min="0"
                          :controls="false"
                          v-model="selectedBoxMap[box.id].num"
                          @blur="onBlur(box)"
                        />
                        <div class="_icon" @click="onSelectBox(box, 1)">
                          <el-icon>
                            <plus />
                          </el-icon>
                        </div>
                      </div>
                    </div>
                  </div>
                </box-container>
              </template>
            </div>
          </template>
        </component>
      </el-scrollbar>
    </div>
  </basic-dialog>
</template>

<script lang="tsx" setup>
import { Minus, Plus } from "@element-plus/icons-vue";

import { getBoxList } from "@/api/box";
import BasicDialog from "@/components/BasicDialog/basicDialog.vue";
import type { BasicTableInstance } from "@/components/BasicTable/basicTable";
import { DataSourceMode } from "@/components/BasicTable/basicTable";
import BasicTable from "@/components/BasicTable/basicTable.vue";
import BoxContainer from "@/components/BoxContainer/box-container.vue";
import Loading from "@/components/Loading/loading.vue";
import PriceBtn from "@/components/PriceBtn/price-btn.vue";
import { priceBy } from "@/enum/common";
import { useMedia } from "@/hooks/useMedia";

import {
  type SelectBoxItem,
  selectPackEmits,
  selectPackProps,
} from "./selectPack";

const props = defineProps(selectPackProps);
const emits = defineEmits(selectPackEmits);

const params = ref<API.BOX.BoxListParams>({});
const basicTableRef = ref<BasicTableInstance>();

const isMobile = useMedia();

const toggle = computed({
  get() {
    return props.open;
  },
  set(isOpen: boolean) {
    emits("update:open", isOpen);
  },
});

const selectedBoxMap = computed({
  get() {
    return props.selectedBox.reduce((map, item) => {
      return {
        ...map,
        [item.id]: item,
      };
    }, {} as Record<number, SelectBoxItem>);
  },
  set(value: Record<number, SelectBoxItem>) {
    emits(
      "update:selectedBox",
      Object.keys(value)
        .map((id) => value[id])
        .filter((item) => item.num && Number(item.num) > 0)
    );
  },
});

function onQuery() {
  basicTableRef?.value?.resetQuery();
}

function onSelectBox(box: API.BOX.BoxListItem, num = 1) {
  const item = selectedBoxMap.value[box.id] || { ...box, num: 0 };
  item.num = Number(item.num) + num;
  selectedBoxMap.value = {
    ...selectedBoxMap.value,
    [item.id]: { ...item },
  };
}

function onBlur(box: API.BOX.BoxListItem) {
  const item = selectedBoxMap.value[box.id];
  selectedBoxMap.value[box.id].num =
    item.num === null || item.num === 0 ? void 0 : item.num;
}
</script>

<style lang="less" scoped>
._form-item {
  @apply flex items-center;
  gap: 1rem;
  ._label {
    font-size: 1rem;
    line-height: 1.38rem;
    white-space: nowrap;
  }
  ._select-search-bar {
    width: 18.75rem;
  }

  &._mobile {
    ._select-search-bar {
      width: 10.69rem;
    }
  }
}

._select-pack-container {
  ._basic-table {
    padding: 1.25rem 0 0.5rem;
    ._box-list {
      @apply flex flex-wrap;
      gap: 0.63rem;
      ._box-item {
        @apply select-none;
        aspect-ratio: 10.89 / 20.06;
        min-height: 0;
        width: calc((100% - 0.63rem * 4) / 5);
        background-color: #373a3b;
        ._box-bottom {
          @apply flex flex-col justify-end w-full;
          height: 2.25rem;
          ._box-number-bar {
            @apply flex items-center justify-between w-full h-full;
            gap: 0.63rem;
            padding: 0 0.56rem;
            ._number-box {
              @apply flex-1 w-0 flex items-center justify-center h-full;
            }

            ._icon {
              @apply flex items-center justify-center;
              width: 1.13rem;
              aspect-ratio: 1/1;
              min-height: 0;
              border-radius: 50%;
              background: #838383;
            }
          }
        }
      }
    }
  }

  &._mobile {
    padding: 1.25rem 1.44rem;
    ._basic-table {
      padding: 0;
      ._box-list {
        @apply flex-wrap;
        gap: 1.81rem;
        ._box-item {
          width: calc((100% - 1.81rem) / 2);
        }
      }
    }
  }
}
</style>

<style lang="less">
._select-pack-container {
  ._scroll-bar {
    height: 100%;
  }
}
</style>
